package com.e2u.util;

import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Properties;

public class SystemUtil
{
	private static boolean isDebugOn = false;
	private static String rootDir = "..";
	private static boolean childClassLoaderFirst = true;
	
	private static final String CONFIG_FILE_NAME = "config.properties";
	
	private static Properties prop = null;
	
	static
	{
		prop = new Properties();
		loadProperties(CONFIG_FILE_NAME);
		
		FileWatchdog fwd = new FileWatchdog(CONFIG_FILE_NAME)
		{
			protected void doOnChange()
			{
				loadProperties(CONFIG_FILE_NAME);
			}
		};
		fwd.setDelay(1000 * 3);
		fwd.start();
	}
	private SystemUtil()
	{
	}
	private static void loadProperties(String fileName)
	{
		try
		{
			ClassLoader cl = SystemUtil.class.getClassLoader();
			System.out.println("ClassLoader of SystemUtil = " + cl);
			InputStream is = cl.getResourceAsStream(fileName);			
			prop.load(is);
			is.close();
			
			isDebugOn = Boolean.parseBoolean(prop.getProperty("DebugOn"));
			rootDir = prop.getProperty("WatchDir");
			childClassLoaderFirst = Boolean.parseBoolean(prop.getProperty("ChildClassLoaderFirst"));
			
			debug("loadProperties from " + fileName + " successfully.");
		}
		catch(Exception e)
		{
			e.printStackTrace(System.out);
		}
	}
	public static String getRootDir()
	{
		return rootDir;
	}
	public static boolean isChildClassLoaderFirst()
	{
		return childClassLoaderFirst;
	}
	
	public static void debug(String str)
	{
		if(isDebugOn)
		{
			System.out.println(str);
		}
	}
	
	public static void testAndInvokeClass(ClassLoader cl, String className, String methodName)
	{
		try
		{
			Class clazz = cl.loadClass(className);
			
			Constructor constructor = clazz.getDeclaredConstructor(null);
			constructor.setAccessible(true);
			
			Object obj = constructor.newInstance();
			
			Method m = clazz.getDeclaredMethod(methodName, null);
			m.setAccessible(true);
			
			m.invoke(obj, null);
		}
		catch(Exception e)
		{
			e.printStackTrace(System.out);
		}
	}
	
	public static Object invoke(Class<?> clazz, String methodName, Class[] parameterTypes, Object[] paramters)
	{
		try
		{
			showClassLoader(clazz);
			Object obj = clazz.newInstance();
			Method m = clazz.getMethod(methodName, parameterTypes);
	        return m.invoke(obj, paramters);
		}
		catch(Exception e)
		{
			e.printStackTrace(System.out);
		}
		return null;
	}
	
	public static Object invoke(Class<?> clazz, String methodName)
	{
		return invoke(clazz, methodName, null, null);
	}
	
	public static void showClassLoader(String prefix, Class<?> clazz)
	{
		System.out.println(prefix + clazz.getName() + " loaded by " + clazz.getClassLoader());
	}
	public static void showClassLoader(Class<?> clazz)
	{
		showClassLoader("", clazz);
	}
}
